import functools
import random

from weiwenhai_Oj.utils import log_utils

logger = log_utils.log('api_common_log')


def log_request_params(func):
    """
    接口日志装饰器

    用于记录接口请求和响应的日志信息。装饰器将记录请求的HTTP方法、请求数据或查询参数、请求者ID以及响应状态和数据。

    使用方法：
    1. 在Django视图函数或DRF视图方法上添加@log_request_params装饰器。
    2. 确保request参数是DRF的Request对象。
    3. 确保接口返回的是Response对象

    示例：
    @log_request_params
    def some_view(request):
        # 视图逻辑
        return Response(data)

     注意事项：
    - 适用于重要的接口或在测试时使用，以便能够详细记录接口的调用情况。
    - 由于日志可能包含敏感信息，请确保在生产环境中根据需要配置日志级别和日志处理。
    """

    @functools.wraps(func)
    def wrapper(request, *args, **kwargs):
        random_request_id = random.randint(100000000, 999999999)  # 生成随机请求ID
        user_id = None
        _request = request.request
        try:
            user_id = request._request.user.id
        except Exception as e:
            logger.error(f"【{random_request_id}】Error getting user_id: {e}")

        if _request.method == 'POST':
            # 如果请求是POST，记录请求数据
            logger.info(
                f"【{random_request_id}】POST: Request name: {func.__name__}, Data: {_request.data}, Requester: {user_id}")
        elif _request.method == 'GET':
            # 如果请求是GET，记录查询参数
            logger.info(
                f"【{random_request_id}】GET: Request name: {func.__name__}, Query params: {_request.query_params}, Requester: {user_id}")
        else:
            # 其他请求方法，记录请求数据和查询参数
            logger.info(
                f"【{random_request_id}】{_request.method}: Request name: {func.__name__}, Data: {_request.data}, Requester: {user_id}")
            logger.info(
                f"【{random_request_id}】{_request.method}: Request name: {func.__name__}, Query params: {_request.query_params}, Requester: {user_id}")

        # 执行被装饰的函数
        response = func(request, *args, **kwargs)

        # 函数执行之后记录响应日志
        response_data = response.data

        # 检查是否有生成器对象，并将其转换为列表
        if isinstance(response_data, dict):
            for key, value in response_data.items():
                if isinstance(value, dict):
                    for subkey, subvalue in value.items():
                        if isinstance(subvalue, (list, tuple)):
                            # 列表或元组中的生成器对象转换为列表
                            value[subkey] = [item for item in subvalue]
                        elif hasattr(subvalue, '__iter__') and not isinstance(subvalue, (str, bytes, dict)):
                            # 其他可迭代对象转换为列表
                            value[subkey] = list(subvalue)
                elif isinstance(value, (list, tuple)):
                    # 列表或元组中的生成器对象转换为列表
                    response_data[key] = [item for item in value]
                elif hasattr(value, '__iter__') and not isinstance(value, (str, bytes, dict)):
                    # 其他可迭代对象转换为列表
                    response_data[key] = list(value)

        logger.info(
            f"【{random_request_id}】Request {func.__name__} completed, Response status: {response.status_code}, Response data: {response_data}, Requester: {user_id}"
        )
        return response

    return wrapper
